﻿package com.google.code.p.ivans.applications;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Scanner;

import com.google.code.p.ivans.entities.Order;
import com.google.code.p.ivans.entities.Waiter;
import com.google.code.p.ivans.myexceptions.EntityNotFoundException;
import com.google.code.p.ivans.serviceinterfaces.OrderServiceInterface;
import com.google.code.p.ivans.serviceinterfaces.WaiterServiceInterface;
import com.google.code.p.ivans.serviceinterfaces.WaitersOrdersServiceInterface;
import com.google.code.p.ivans.serviceinterfacesimpls.OrderServiceInterfaceImpl;
import com.google.code.p.ivans.serviceinterfacesimpls.WaiterServiceInterfaceImpl;
import com.google.code.p.ivans.serviceinterfacesimpls.WaitersOrdersServiceInterfaceImpl;

import org.apache.log4j.Logger;

/*
 * Задание 4. Исключения и логирование
 * */
public class Application_4 {
	
	public static final Logger logger= Logger.getLogger(Application_4.class);

	public static void main(String[] args){
		WaiterServiceInterface waiterSI = new WaiterServiceInterfaceImpl();
		OrderServiceInterface orderSI = new OrderServiceInterfaceImpl();
		WaitersOrdersServiceInterface waitersOrdersSI = new WaitersOrdersServiceInterfaceImpl();
		
		Scanner scanner = new Scanner(System.in);
		BufferedReader bufread = new BufferedReader(new InputStreamReader(System.in));	
				
		int mainChoise;			
		
		printMenu("ГЛАВНОЕ МЕНЮ",
			"Официанты - 1\n" +
			"Заказы - 2\n" + 
			"Заказы_и_официанты - 3\n" +
			"Выход - 0"
		);
		
		while((mainChoise = scanner.nextInt()) != 0) {
			//официанты
			if(mainChoise == 1) {
				
				//logger.DEBUG
				if(logger.isDebugEnabled()){
					logger.debug("[DEBUG]Главное меню -> Официанты - 1");
				}
				
				printMenu("ОФИЦИАНТЫ",
					"Создать - 1\n" +
					"Открыть - 2\n" +
					"Список всех - 3\n" +
					"Выход - 0"
				);
				
				int waiterChoise;
				
				while((waiterChoise = scanner.nextInt()) != 0) {
					
					//создать официанта
					if(waiterChoise == 1){
						
						//logger.DEBUG
						if(logger.isDebugEnabled()){
							logger.debug("[DEBUG]Главное меню -> Официанты -> Создать - 1");
						}
						
						String first = "";
						String last = "";
						String patronymic = "";
						int dayBorn = 0;
						int monthBorn = 0;
						int yearBorn = 0;
						int salary = 0;
						
						try{							
							println("Введите Имя:");
							while((first = bufread.readLine()).length() < 1) {}
							
							
							println("Введите Фамилию:");
							while((last = bufread.readLine()).length() < 1) {}							
						
							
							println(">>Введите Отчество:");
							while((patronymic = bufread.readLine()).length() < 1) {}
							
							println(">>Введите день рождения:");
							dayBorn = scanner.nextInt();
							
							println(">>Введите месяц рождения:");
							monthBorn = scanner.nextInt();
							
							println(">>Введите год рождения:");
							yearBorn = scanner.nextInt();
							
							println(">>Введите зарплату:");
							salary = scanner.nextInt();	
						
							Waiter waiter = new Waiter(first, last, patronymic, 
													new GregorianCalendar(yearBorn, monthBorn, dayBorn),
													new GregorianCalendar(),
													salary);
							waiterSI.addWaiter(waiter);
							println("ОФИЦИАНТ ДОБАВЛЕН");	
							
							if(logger.isInfoEnabled()){
								logger.info("[INFO]Создали официанта:\n" + waiter.toString());
							}
						}
						catch(IllegalArgumentException enfexc) {
							println("Не удалось создать объект. Причина - " + enfexc.getMessage());
							//enfexc.printStackTrace();
							
							//logger.ERROR
							logger.error("[ERROR]Не удалось создать объект. Причина - " + enfexc.getMessage());
						}
						catch(IOException ioexc) {
							println("Ошибка чтения данных. Причина - " + ioexc.getMessage());

							logger.error("[ERROR]Ошибка чтения данных. Причина - " + ioexc.getMessage());
						}
						
					}//конец создания официанта
					
					//открыть официанта
					else if(waiterChoise == 2){
						
						//logger.DEBUG
						if(logger.isDebugEnabled()){
							logger.debug("[DEBUG]Главное меню -> Официанты -> Открыть - 2");
						}
						
						printMenu("ПОИСК ОФИЦИАНТА",
								"Открыть по ID - 1\n" +
								"Поиск по имени - 2\n" +
								"Выход - 0"
								);
						
						int openWaiterChoise;
						while((openWaiterChoise = scanner.nextInt()) != 0) {							
							
							//открыть по ID
							if(openWaiterChoise == 1){
								
								//logger.DEBUG
								if(logger.isDebugEnabled()){
									logger.debug("[DEBUG]Главное меню -> Официанты -> Открыть -> по ID - 1");
								}
								
								int id;
								println(">>Введите ID официанта");								
								id = scanner.nextInt();
								
								try{
									Waiter waiter = waiterSI.getByID(id);
									println("\n" + waiter + "\n");
									
									//logger.INFO
									if(logger.isInfoEnabled()){
										logger.info("[INFO]Просмотр официанта:\n" + waiter.toString());
									}
								}
								
								catch(EntityNotFoundException exc) {
									println("Отсутствует официант с данным id");
									
									logger.error("[ERROR]Отсутствует официант с данным id");
									//exc.printStackTrace();
								}							
								
							}//end открыть по ID
							
							//поиск по имени
							else if(openWaiterChoise == 2){
								
								//logger.DEBUG
								if(logger.isDebugEnabled()){
									logger.debug("[DEBUG]Главное меню -> Официанты -> Открыть -> по ФИО - 2");
								}
								
								String first_ = "";
								String last_ = "";
								String patronymic_ = "";
								try{									
									
									println(">>Введите имя");
									while((first_ = bufread.readLine()).length() < 1) {}
									
	
									println(">>Введите фамилию");
									while((last_ = bufread.readLine()).length() < 1) {}
	
									println(">>Введите отчество");
									while((patronymic_ = bufread.readLine()).length() < 1) {}
									
									List<Waiter> seached;
									try {
										seached = waiterSI.getAllWaitersByName(first_, last_, patronymic_);
										println("----------------------");
										println("Результаты:" + seached.size() +"\n");
										String result = showWaiters(seached);
										
										//logger.INFO
										if(logger.isInfoEnabled()){
											logger.info("[INFO]Поиск официантов по имени:\n" + result);
										}
									} 
									catch (EntityNotFoundException e) {
										println("Отсутствуют официанты с данным именем");
										
										logger.error("[ERROR]Отсутствуют официанты с данным именем");
										//e.printStackTrace();
									}						
									
								}
								catch(IOException ignore) {
									logger.error("[ERROR]IOException on reading");
								}
								
							}//end поиск по имени				
														

							printMenu("ПОИСК ОФИЦИАНТА",
									"Открыть по ID - 1\n" +
									"Поиск по имени - 2\n" +
									"Выход - 0"
									);
						}//end while((openWaiterChoise = scanner.nextLine()) != 0)
						
						
					}//end открыть официанта
					
					//список всех сотрудников
					else if(waiterChoise == 3){
						
						//logger.DEBUG
						if(logger.isDebugEnabled()){
							logger.debug("[DEBUG]Главное меню -> Официанты -> Список всех - 3");
						}
						
						List<Waiter> allWaiters = waiterSI.getAllWaiters();
						
						if(allWaiters.size() == 0) {
							println("ОФИЦИАНТЫ ОТСУТСТВУЮТ\n");
							
							logger.error("[ERROR]Хранилище официантов пусто");
						}
						else {
							println("Все официанты:");
							println("------------------------------------------------------------------------------------");
							String result = showWaiters(allWaiters);
							println("------------------------------------------------------------------------------------");							
						
							//logger.INFO
							if(logger.isInfoEnabled()){
								logger.info("[INFO]Просмотр всех официантов:\n" + result);
							}
						}
						
						
					}//end список всех сотрудников					
					
					printMenu("ОФИЦИАНТЫ",
							"Создать - 1\n" +
							"Открыть - 2\n" +
							"Список всех - 3\n" +
							"Выход - 0"
						);
				}				
			}
			
			//заказы
			else if(mainChoise == 2){
				
				//logger.DEBUG
				if(logger.isDebugEnabled()){
					logger.debug("[DEBUG]Главное меню -> Заказы - 2");
				}
				
				int orderChoise;
				
				printMenu("ЗАКАЗЫ", 
						"Создать - 1\n" +
						"Открыть - 2\n" +
						"Список всех - 3\n" +
						"Выход - 0");
				
				while((orderChoise = scanner.nextInt()) != 0) {	
				
					//создать заказ
					if(orderChoise == 1) {
						
						//logger.DEBUG
						if(logger.isDebugEnabled()){
							logger.debug("[DEBUG]Главное меню -> Заказы -> Создать - 1");
						}
						
						int table = -1; 
						String dishes;
						try
						{
							println(">>Введите номер столика:");
							table = scanner.nextInt();
							
							println(">>Введите блюда через запятую:");
							dishes = bufread.readLine();
							
							Order order = new Order(table,dishes.split(","), 
									new GregorianCalendar(2013, Calendar.DECEMBER, 10));
							orderSI.addOrder(order);
							
							println("ЗАКАЗ ДОБАВЛЕН!");
							
							//logger.INFO
							if(logger.isInfoEnabled()){
								logger.info("[INFO]Добавлен заказ:\n" + order.toString());
							}
						}
						catch(IllegalArgumentException exc) {
							println("Не удалось создать заказ. Причина - " + exc.getMessage());
							
							logger.error("[ERROR]Не удалось создать заказ. Причина - " + exc.getMessage());
							//exc.printStackTrace();
						}
						catch(IOException exc) {
							logger.error("[ERROR]IOException. Причина - " + exc.getMessage());
							exc.printStackTrace();
						}
						
					}//end создать заказ
					
					//открыть заказ
					else if(orderChoise == 2) {
						
						//logger.DEBUG
						if(logger.isDebugEnabled()){
							logger.debug("[DEBUG]Главное меню -> Заказы -> Открыть - 2");
						}
						
						println(">>Введите id заказа");
						int id = scanner.nextInt();
						
						Order ord;						
						try {
							ord = orderSI.getOrderByID(id);
							println(ord.toString());
							
							//logger.INFO
							if(logger.isInfoEnabled()){
								logger.info("[INFO]Открыли заказ:\n" + ord.toString());
							}
						} 
						catch (EntityNotFoundException e) {
							println("Отсутствует заказ с данным id");
							
							logger.error("[ERROR]Отсутствует заказ с данным id");
							//e.printStackTrace();
						}						
					}//end открыть заказ
					
					//список заказов
					else if(orderChoise == 3) {
						
						//logger.DEBUG
						if(logger.isDebugEnabled()){
							logger.debug("[DEBUG]Главное меню -> Заказы -> Список заказов - 3");
						}
						
						List<Order> allOrders = orderSI.getAllOrders();						
						
						if(allOrders.size() == 0) {
							println("ЗАКАЗЫ ОТСУТСТВУЮТ\n");
							
							logger.error("[ERROR]Хранилище заказов пусто");
						}
						else {
							println("Все заказы:");
							println("------------------------------------");
							StringBuilder bld = new StringBuilder();
							for(int i = 0; i < allOrders.size(); i++) {
								//System.out.println();
								System.out.println(allOrders.get(i));
								System.out.println();
								bld.append(allOrders.get(i).toString());
								bld.append("\n");
							}
							println("------------------------------------");	
							
							//logger.INFO
							if(logger.isInfoEnabled()){
								logger.info("[INFO]Открыли заказы:\n" + bld.toString());
							}
						}
							
					}//end список заказов
					
					printMenu("ЗАКАЗЫ", 
							"Создать - 1\n" +
							"Открыть - 2\n" +
							"Список всех - 3\n" +
							"Выход - 0");					
				}//end цикл по заказам
				
			}//end choise == заказы
			
			//заказы и столики
			else if(mainChoise == 3) {
				
				//logger.DEBUG
				if(logger.isDebugEnabled()){
					logger.debug("[DEBUG]Главное меню -> Заказы_и_столики - 3");
				}
				
				long waiterID;
				long orderID;
				
				println(">>Введите id официанта");
				waiterID = scanner.nextLong();
				

				println(">>Введите id заказа");
				orderID = scanner.nextLong();
				
				Waiter w;
				Order o;
				try {
					w = waiterSI.getByID(waiterID);
					o = orderSI.getOrderByID(orderID);
					
					waitersOrdersSI.addLink(waiterID, orderID);
					println("СВЯЗЬ ДОБАВЛЕНА!");	
					
					//logger.INFO
					if(logger.isInfoEnabled()){
						logger.info("[INFO]Добавили связь между " + waiterID + " официантом и " + orderID + " заказом");
					}
				} 
				catch (EntityNotFoundException e) {
					println("Отсутстсвует официант или заказ с данным id");
					
					logger.error("[ERROR]Отсутстсвует официант или заказ с данным id");
					//e.printStackTrace();
				}
				
			}//end заказы и столики
			else {
				System.exit(0);
			}	
			
			printMenu("ГЛАВНОЕ МЕНЮ",
					"Официанты - 1\n" +
					"Заказы - 2\n" + 
					"Заказы_и_официанты - 3\n" +
					"Выход - 0");			
			
		}//end while((waiterChoise = scanner.nextInt()) != 0)

	}	
	
        
	public static void println(String str) {
		System.out.println(str);
	}
	
	public static void printMenu(String label, String items) {
		System.out.println("----------------------\n---" + label + "---");
		System.out.println(items);
		//System.out.println("-----------------------");
		System.out.println(">>");
	}
	
	public static String showWaiters(List<Waiter> waiters) {
		if(waiters == null)
			return null;
		
		if(waiters.size() == 0)
			return null;
		
		StringBuilder all = new StringBuilder();
		String label = "ID   ФИО                                         Зарплата Дата рождения Дата принятия ";
		all.append(label);
		all.append("\n");
		
		System.out.println(label);
				
		for(int i = 0; i < waiters.size(); i++) {
			long id = waiters.get(i).getWaiterID();
			int signs = 0;
			while(id != 0) {
				id /= 10;
				signs++;
			}
			
			StringBuilder builder = new StringBuilder();
 			builder.append(waiters.get(i).getWaiterID());
 			
 			for(int j = signs; j < 5; j++) {
 				builder.append(' ');
 			}
 			
 			String FIO = waiters.get(i).getLastName() + " " + waiters.get(i).getFirstName() + " " + waiters.get(i).getPatronymicName();
 			builder.append(FIO);
 	
 			for(int j = FIO.length(); j < 44; j++) {
 				builder.append(' ');
 			}
 			
 			int salary = waiters.get(i).getSalary();
 			signs = 0;
 			while(salary != 0) {
				salary /= 10;
				signs++;
			}
 			
 			builder.append(waiters.get(i).getSalary());
 			for(int j = signs; j < 9; j++) {
 				builder.append(' ');
 			}
 			
 			GregorianCalendar bornDate = waiters.get(i).getBornDate();
 			
 			int day = bornDate.get(Calendar.DAY_OF_MONTH);
 			int month = (bornDate.get(Calendar.MONTH) + 1); 			
 			String born = ((day < 10) ? "0" + day:day)   + "-" + ((month < 10) ? "0" + month:month) + "-" + bornDate.get(Calendar.YEAR) + "    ";
 			
 			builder.append(born);  
 			
 			GregorianCalendar hireDate = waiters.get(i).getHireDate();
 			
 			day = hireDate.get(Calendar.DAY_OF_MONTH);
 			month = (hireDate.get(Calendar.MONTH) + 1); 
 			String hire = ((day < 10) ? "0" + day:day)   + "-" + ((month < 10) ? "0" + month:month) + "-" + hireDate.get(Calendar.YEAR) + "    ";
 			
 			builder.append(hire); 
 			System.out.println(builder.toString());
 			all.append(builder);
 			all.append("\n");
		}
		return all.toString();
	}	
}
